﻿// ===============================================================================
//  Copyright © ymind.net. All rights reserved .
//  官方网站：http://ymind.net/
//  版权所有：彦铭工作室 老陈出品
// ===============================================================================

using System;
using System.Runtime.InteropServices;
using System.Text;
using Lcsoft.TemplateEngine.XHtmlParser;

namespace Lcsoft.TemplateEngine.Tags
{
	/// <summary>
	/// 为模板引擎语句标签提供基类。
	/// </summary>
	[ComVisible(true)]
	[Serializable]
	public abstract class TemplateElement : XHtmlElement
	{
		/// <summary>
		/// 初始化模板引擎语句标签。
		/// </summary>
		/// <param name="prefix">模板引擎语句标签的前缀名。</param>
		/// <param name="name">标签名。</param>
		/// <param name="line">标签所在的行数。</param>
		/// <param name="column">标签所在的列数。</param>
		protected TemplateElement(string prefix, string name, int line, int column) : base(name, line, column)
		{
			if (prefix == null) throw new ArgumentNullException("prefix");
			if (prefix.Length == 0) throw new ArgumentOutOfRangeException("prefix");

			this.Prefix = prefix;
		}

		/// <summary>
		/// 获取模板引擎语句标签的前缀名。
		/// </summary>
		public string Prefix { get; private set; }

		/// <summary>
		/// 获取缩进数量。
		/// </summary>
		public override int Indents
		{
			get
			{
				var indents = 2;

				XHtmlNode node = this;

				while (true)
				{
					if (node.Parent == null) break;

					node = node.Parent;

					if (node is ImportantTag) continue;

					var element = node as TemplateElement;

					if (element == null) break;

					indents++;
				}

				return indents;
			}
		}

		/// <summary>
		/// 获取一个值，该值指示当前标签是否已被禁用。
		/// </summary>
		public bool Disabled
		{
			get { return TemplateEngineHelper.ToBoolean(this.GetAttributeValue("disabled")); }
		}

		/// <summary>
		/// 返回包含 <see cref="TemplateElement"/> 内容的 .html 格式的字符串。
		/// </summary>
		/// <returns>返回 <see cref="System.String"/>。</returns>
		public override string ToHtml()
		{
			var html = new StringBuilder();

			html.AppendFormat("<{0}:{1}", this.Prefix, this.Name);

			foreach (var attribute in this.Attributes.Values) html.AppendFormat(" {0}", attribute.ToHtml());

			if (this.Nodes.Count > 0)
			{
				html.Append(">");

				foreach (var node in this.Nodes) html.Append(node.ToHtml());

				html.AppendFormat("</{0}:{1}>", this.Prefix, this.Name);
			}
			else
			{
				if (this.IsExplicitlyTerminated) html.AppendFormat("></{0}:{1}>", this.Prefix, this.Name);
				else if (this.IsTerminated) html.Append(" />");
				else html.Append(">");
			}

			return html.ToString();
		}

		/// <summary>
		/// 返回包含 <see cref="TemplateElement"/> 内容的 .aspx 格式的字符串。
		/// </summary>
		/// <returns>返回 <see cref="System.String"/>。</returns>
		public override string ToAspx()
		{
			var aspx = new StringBuilder();

			aspx.AppendFormat("<{0}:{1}", this.Prefix, this.Name);

			foreach (var attribute in this.Attributes.Values) aspx.AppendFormat(" {0}", attribute.ToHtml());

			if (this.Nodes.Count > 0)
			{
				aspx.Append(">");

				foreach (var node in this.Nodes) aspx.Append(node.ToAspx());

				aspx.AppendFormat("</{0}:{1}>", this.Prefix, this.Name);
			}
			else
			{
				if (this.IsExplicitlyTerminated) aspx.AppendFormat("></{0}:{1}>", this.Prefix, this.Name);
				else if (this.IsTerminated) aspx.Append(" />");
				else aspx.Append(">");
			}

			return aspx.ToString();
		}

		/// <summary>
		/// 返回表示 <see cref="TemplateElement"/> 的字符串。
		/// </summary>
		/// <returns>返回 <see cref="System.String"/>。</returns>
		public override string ToString()
		{
			var html = new StringBuilder();

			html.AppendFormat("<{0}:{1}", this.Prefix, this.Name);

			foreach (var attribute in this.Attributes.Values) html.AppendFormat(" {0}", attribute);

			html.Append(">");

			return html.ToString();
		}
	}
}
